import { Inject, Module, OnApplicationBootstrap } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AaaModule } from './aaa/aaa.module';
import { BbbModule } from './bbb/bbb.module';
import { CccModule } from './ccc/ccc.module';
import { WinstonModule } from './winston/winston.module';
import * as chalk from 'chalk';
import { createLogger, format, Logger, transports } from 'winston';
import { UserModule } from './user/user.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user/entities/user.entity';
import { CityModule } from './city/city.module';
import { City } from './city/entities/city.entity';
import { ArticleModule } from './article/article.module';
import { Article } from './article/entities/article.entity';
import { ConfigModule } from '@nestjs/config';
import * as path from 'path';
import config from './config';
import config2 from './config2';
import { createClient } from 'redis';
import { JwtModule } from '@nestjs/jwt';
import { LoginUserModule } from './login-user/login-user.module';
import { LoginUser } from './login-user/entities/login-user.entity';
import { Permission } from './login-user/entities/permission.entity';
import { RedisModule } from './redis/redis.module';
import { RbacUserModule } from './rbac_user/rbac_user.module';
import { RbacUser } from './rbac_user/entities/rbac_user.entity';
import { RbacRole } from './rbac_user/entities/rbac_role.entity';
import { RbacPermission } from './rbac_user/entities/rbac_permission.entity';
import { Aaa2Module } from './aaa2/aaa2.module';
import { Bbb2Module } from './bbb2/bbb2.module';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { RbacLoginGuard } from './rbac-login.guard';
import { RbacPermissionGuard } from './rbac-permission.guard';
import { Aaa3Module } from './aaa3/aaa3.module';
import { AuthModule } from './auth/auth.module';
import { JwtAuthGuard } from './auth/JwtAuthGuard';
import { GithubUser } from './login-user/entities/github-user.entity';
import { SessionModule } from './session/session.module';
import { Aaa4Module } from './aaa4/aaa4.module';
import { Aaa5Module } from './aaa5/aaa5.module';
import { Aaa6Module } from './aaa6/aaa6.module';
import { Aaa7Module } from './aaa7/aaa7.module';
import { MailUserModule } from './mail-user/mail-user.module';
import { MailUser } from './mail-user/entities/mail-user.entity';
import { ArticleViewsModule } from './article-views/article-views.module';
import { User2 } from './article-views/entities/user2.entity';
import { Article2 } from './article-views/entities/article2.entity';
import { ScheduleModule, SchedulerRegistry } from '@nestjs/schedule';
import { TaskModule } from './task/task.module';
import { CronJob } from 'cron';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { Aaa8Module } from './aaa8/aaa8.module';
import { CityWeatherModule } from './city-weather/city-weather.module';
import { RequestLogInterceptor } from './request-log.interceptor';
import { HttpModule } from '@nestjs/axios';
import { UniqueCodeModule } from './unique-code/unique-code.module';
import { UniqueCode } from './unique-code/entities/UniqueCode';
import { ShortLongMap } from './unique-code/entities/ShortLongMap';
import { SseModule } from './sse/sse.module';
import { MinioModule } from './minio/minio.module';
import { Aaa9Module } from './aaa9/aaa9.module';
import { BossSpiderModule } from './boss-spider/boss-spider.module';
import { Job } from './boss-spider/entities/job.entities';
import { QrcodeLoginModule } from './qrcode-login/qrcode-login.module';
import { ExcelTestModule } from './excel-test/excel-test.module';
import { PptCreateModule } from './ppt-create/ppt-create.module';
import { ServerStatusModule } from './server-status/server-status.module';
import { AcceptLanguageResolver, CookieResolver, HeaderResolver, I18nModule, QueryResolver } from 'nestjs-i18n';
import { I18nTestModule } from './i18n-test/i18n-test.module';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { Etcd3 } from 'etcd3';
import { EtcdModule } from './etcd/etcd.module';
import { EtcdTestModule } from './etcd-test/etcd-test.module';
import { NacosModule } from './nacos/nacos.module';
import { PrismaService } from './prisma.service';
import { DepartmentService } from './department.service';
import { EmployeeService } from './employee.service';
import { FollowModule } from './follow/follow.module';
import { FUser } from './follow/entities/fuser.entity';
import { RankingModule } from './ranking/ranking.module';
import { WebsocketModule } from './websocket/websocket.module';
import { ChatroomModule } from './chatroom/chatroom.module';


@Module({
  imports: [
    LoginUserModule,
    AaaModule,
    BbbModule,
    CccModule.register({ aaa: 1, bbb: '2', isGlobal: true }),
    WinstonModule.forRoot({
      level: 'debug',
      transports: [
        new transports.Console({
          format: format.combine(
            format.colorize(),
            format.printf(({ context, level, message, time }) => {
              const appStr = chalk.green(`[NEST]`);
              const contextStr = chalk.yellow(`[${context}]`);
              return `${appStr} ${time} ${level} ${contextStr} ${message}`;
            }),
          ),
        }),
        new transports.File({
          format: format.combine(format.timestamp(), format.json()),
          filename: '111.log',
          dirname: 'log',
        }),
      ],
    }),
    HttpModule.register({
      timeout: 5000,
    }),
    UserModule,
    ConfigModule.forRoot({
      isGlobal: true,
      // envFilePath: [path.join(process.cwd(), '.aaa.env'), path.join(process.cwd(), '.env'), ],
      envFilePath: [path.join(process.cwd(), '.aaa.env'), path.join(__dirname, '.env'), ],
      // load: [config2, config],
    }),
    ScheduleModule.forRoot(),
    EventEmitterModule.forRoot(),
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      // host: '10.1.22.152',
      // host: 'mysql-container',
      port: 3305,
      username: 'root',
      password: '111111',
      // database: 'nest-migration-test',
      database: 'login_test',
      synchronize: true,
      logging: true,
      // entities: [User],
      // entities: [Article],
      // entities: [LoginUser, Permission], // acl权限控制
      // entities: [
      //   LoginUser,
      //   Permission,
      //   RbacUser,
      //   RbacRole,
      //   RbacPermission,
      //   GithubUser,
      // ],
      // entities: [MailUser],
      // entities: [
      //   LoginUser,
      //   Permission,
      //   Article2,
      //   User2
      // ],
      // entities: [UniqueCode, ShortLongMap],
      // entities: [Job],
      entities: [FUser],
      poolSize: 10,
      connectorPackage: 'mysql2',
      extra: {
        authPlugin: 'sha256_password',
      },
    }),
    CityModule,
    ArticleModule,
    JwtModule.register({
      global: true,
      secret: 'ABIN',
      signOptions: {
        expiresIn: '7d', // 过期时间
      },
    }),
    I18nModule.forRoot({
      fallbackLanguage: 'en',
      loaderOptions: {
        path: path.join(__dirname, '/i18n/'),
        watch: true
      },
      resolvers: [
        new QueryResolver(['lang', 'l']), // 从哪里读取当前语言信息，这里是从 query 中读取，比如 ?lang=en、?l=zh
        new HeaderResolver(['x-custom-lang']),
        new CookieResolver(['lang']),
        AcceptLanguageResolver
      ]
    }),
    RedisModule,
    RbacUserModule,
    Aaa2Module,
    Bbb2Module,
    Aaa3Module,
    AuthModule,
    SessionModule,
    Aaa4Module,
    Aaa5Module,
    Aaa6Module,
    Aaa7Module,
    MailUserModule,
    ArticleViewsModule,
    TaskModule,
    Aaa8Module,
    CityWeatherModule,
    UniqueCodeModule,
    SseModule,
    MinioModule,
    Aaa9Module,
    BossSpiderModule,
    QrcodeLoginModule,
    ExcelTestModule,
    PptCreateModule,
    ServerStatusModule,
    I18nTestModule,

    // JwtModule.registerAsync({
    //   async useFactory() {
    //     await 111
    //     return {
    //       secret: 'ABIN',
    //       signOptions: {
    //         expiresIn: '7d'
    //       }
    //     }
    //   }
    // }
    // CccModule.registerAsync({
    //   async useFactory(...args) {
    //       await 111
    //       return {
    //         aaa: 222,
    //         bbb: 'bbb',

    //       }
    //   },
    // })
    ClientsModule.register([
      {
        name: 'USER_SERVICE',
        transport: Transport.TCP,
        options: {
          port: 8888
        }
      },
      {
        name: 'BOOK_PACKAGE',
        transport: Transport.GRPC,
        options: {
          url: 'localhost:8888',
          package: 'book',
          protoPath: path.join(__dirname, 'book/book.proto')
        }
      }
    ]),

    EtcdModule,

    // EtcdTestModule,

    NacosModule,

    FollowModule,

    RankingModule,

    WebsocketModule,

    ChatroomModule,

  ],
  controllers: [AppController],
  providers: [
    AppService,
    // {
    //   provide: 'REDIS_CLIENT',
    //   async useFactory(...args) {
    //     const client = createClient({
    //       socket: {
    //         host: 'localhost',
    //         port: 6379,
    //       },
    //     });
    //     await client.connect();
    //     return client;
    //   },
    // },
    // {
    //   provide: APP_GUARD,
    //   useClass: RbacLoginGuard,
    // },
    {
      provide: APP_GUARD,
      useClass: RbacPermissionGuard,
    },
    // {
    //   provide: APP_GUARD,
    //   useClass: JwtAuthGuard
    // },
    {
      provide: APP_INTERCEPTOR,
      useClass: RequestLogInterceptor
    },
    {
      provide: 'ETCD_CLIENT',
      useFactory() {
        const client = new Etcd3({
          hosts: 'http://localhost:2379',
          auth: {
            username: 'root',
            password: 'abinabin'
          }
        })
        return client
      }
    },
    PrismaService,
    DepartmentService,
    EmployeeService
  ],
})
export class AppModule implements OnApplicationBootstrap{
  @Inject(SchedulerRegistry)
  private schedulerRegistry: SchedulerRegistry

  onApplicationBootstrap() {
    // const crons  = this.schedulerRegistry.getCronJobs()
    // crons.forEach((item, key) => {
    //   item.stop()
    //   this.schedulerRegistry.deleteCronJob(key)
    // })

    // const intervals = this.schedulerRegistry.getIntervals()
    // intervals.forEach((item, key) => {
    //   const interval = this.schedulerRegistry.getInterval(item)
    //   clearInterval(interval)
    //   this.schedulerRegistry.deleteInterval(item)
    // })

    // const timeouts = this.schedulerRegistry.getTimeouts()
    // timeouts.forEach((item) => {
    //   const timeout = this.schedulerRegistry.getTimeout(item)
    //   clearTimeout(timeout)
    //   this.schedulerRegistry.deleteTimeout(item)
    // })

    // console.log(this.schedulerRegistry.getCronJobs())
    // console.log(this.schedulerRegistry.getIntervals())
    // console.log(this.schedulerRegistry.getTimeouts())

    // const job = new CronJob(`0/5 * * * * *`, () => {
    //   console.log('cron job')
    // })
    // this.schedulerRegistry.addCronJob('job1', job)
    // job.start()

    // const timeout = setTimeout(() => {
    //   console.log('timeout job')
    // }, 5000);
    // this.schedulerRegistry.addTimeout('job2', timeout)

    // const interval = setInterval(() => {
    //   console.log('interval job')
    // }, 3000)
    // this.schedulerRegistry.addInterval('job3', interval)

  }
  
}
